programming4us
           
 
 
Programming

iPad SDK : Popovers - Popover Preparations

- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019
3/8/2011 3:34:35 PM
Up until recently, the iOS user interface paradigm supported showing only a limited amount of material on the screen at any point in time. In a Cocoa Touch application, there's typically one view controller in focus at a time, and that view controller is in charge of the whole screen (or most of it). The notable exceptions are classes like UINavigationController and UITabBarController, which don't display any interesting content on their own, but instead help developers organize other view controllers.

On the small screen of the iPhone and the iPod touch, this makes a lot of sense. Instead of a profusion of tiny widgets fighting for space on the screen, iOS users have gotten used to being able to focus on one thing at a time, with new views sliding into place when on-screen objects or controls are used. This paradigm is so widely used that even controls that would take up just a small space on a desktop computer, such as a popup list, fill the iPhone's screen when you activate them. On the iPad, however, this behavior isn't always suitable. Sometimes, you need to display a little GUI in order to choose an option, such as from a popup list. Filling the larger iPad screen with a simple list of items would feel both unnatural and wasteful of that nice screen real estate!

The new UIPopoverController class in iOS 3.2 lets you display an auxiliary view that floats in front of the other on-screen content, without filling the entire screen. Like the UINavigationController and UITabBarController, UIPopoverController doesn't display any interesting content on its own. Instead, it serves an organizational role and acts as a container for your own view controllers.

1. Popover Preparations

So far, Dudel serves as a nice demo of a few features, but it's extremely limited in comparison to the vector-drawing applications that have been around for decades. One of the main features it lacks is the ability to change the properties of what you're drawing. Right now, you're stuck with the line width, stroke and fill colors, and font that the app gives you from the outset. It's time to change all that!

We're going to create GUIs that let users change all those attributes, giving users much more control over their creations. Each of these attributes requires a little different approach to setting them, and therefore a different sort of GUI:

  • Selecting a font will occur through a simple list that displays the name of each font, rendered in that font itself.

  • The font's size will be set using a slider in a popup, with a preview showing a piece of text rendered at the chosen size.

  • A popup with a slider will let you set the line width, again with a built-in preview.

  • Another popup will let you choose the fill and stroke colors from a predefined grid of colors.

The idea is for you to learn several ways that popovers can be used in a real application, starting with the simplest type and working up to more complicated examples.

Before we proceed, let's clarify a point about the concept of a selected object, and the context to which the attributes you set will be applied. Most vector-drawing applications include some sort of selector tool that lets you click an object you've drawn, which then becomes highlighted and editable in some way. Any changes you make to color settings, line width, and so on are typically applied immediately to the selected object. In Dudel, however, we have none of that. There's never a selected object, and therefore never any visible item to which your attribute settings are applied. Instead, the settings are remembered in a central spot (the DudelViewController class), where they will be used for the next thing you draw.

1. The Basic GUI

Let's start off by making some modifications to the main GUI in DudelViewController. We're going add a set of new UIBarButtonItems at the bottom of the screen for the popovers, each with a new icon. Unlike the icons for the tools we created earlier, these don't need to have any sort or highlighting state, so just a single icon for each is fine. Table 1 shows the icons you'll need for this article. Add these images, using the filenames listed in Table 1, to your project.

Table 1. New Buttons for the Popovers
FilenameImage
button_strokewidth.png
button_strokecolor.png
button_fillcolor.png
button_fontname.png
button_fontsize.png

Now let's add action methods to our controller class's interface for connecting these buttons. Open DudelViewController.h, and somewhere near the end of the file, but before the @end line, add the following lines:

- (IBAction)popoverFontName:(id)sender;
- (IBAction)popoverFontSize:(id)sender;
- (IBAction)popoverStrokeWidth:(id)sender;
- (IBAction)popoverStrokeColor:(id)sender;
- (IBAction)popoverFillColor:(id)sender;

Then, just to keep our code in a compilable state, switch over to DudelViewController.m and insert some empty implementations for those methods inside the @implementation DudelViewController section:

- (IBAction)popoverFontName:(id)sender {
}
- (IBAction)popoverFontSize:(id)sender {
}
- (IBAction)popoverStrokeWidth:(id)sender {
}
- (IBAction)popoverStrokeColor:(id)sender {
}
- (IBAction)popoverFillColor:(id)sender {
}

We'll go back and fill in the implementations of those methods a little later, but first we want to hook up the GUI. Save your work, and then open DudelViewController.xib in Interface Builder. We'll add the new buttons as a group, between the group of tools on the left and the e-mail action on the right, as shown in Figure 1.

Figure 1. Positioning the settings buttons

First, duplicate the flexible space object in place, by selecting it and pressing =>D. That will give you a location to put more buttons. Then use the Library to find a UIBarButtonItem and drag it out between the two flexible spaces. Next, open the attribute inspector. Set the new item's Style to Plain, and set its image to button_strokewidth.png. This gives us the basic template for how all five buttons will appear. While the new item is still selected, press =>D four times to make a row of five identical items.

Now we need to add the actions and images to the buttons. Select the leftmost item, control-drag to the File's Owner icon in the main .nib window, and click popoverStrokeWidth: in the list of actions that appears. Then go along the rest of the row, configuring each item's action and connecting it to the appropriate image. The second item should get the popover_strokecolor.png image and be connected to popoverStrokeColor:. The third should use popover_fillcolor.png and popoverFillColor:. The last two items are for choosing a font name and font size, and I'll bet that by now, you can figure out which images and actions to use for them.

2. Popover Considerations

One of the main uses for popovers is to present a list of selectable items, not unlike the menus available in Mac OS X and other desktop operating systems. When using menus in a Mac OS X application, the system takes care of things such as making sure that only one menu is shown at a time and making the menu disappear when an item is selected. But the popover in iOS is a different beast.

A popover won't automatically disappear when the user selects something inside it, and opening one popover doesn't remove any previously opened popover from the screen. This means that you could easily wind up with multiple popovers on the screen at once, overlapping each other.

The only time the system automatically closes a popover is when you touch some part of the screen outside the popover (except, notably, touching an item in a UIToolbar, which leaves the popover just as it is). The rest of the time, you'll need to dismiss the popover yourself any time a user action warrants it.

However, this apparent lack of automation actually gives you some amount of flexibility compared to what's typically possible with a menu. A popover can, for instance, contain interactive controls, such as sliders or check boxes, to let the user quickly try out different possibilities and see the results instantly. That wouldn't be possible if the popover went away as soon as someone clicked it. Similarly, allowing multiple popovers to be displayed simultaneously may be useful in situations where you want to let the user quickly change multiple settings or attributes. For example, in a word processing app, you might want to let the user open two popovers: one for selecting from a list of fonts, and one for toggling attributes (bold, italics, underline, and so on).

NOTE

Apple recommends against displaying multiple popovers at once, in order to avoid "confusing" your users, so think twice before going that route.

In Dudel, we're going to allow for only one popover at a time by keeping an instance variable in DudelViewController that points at the current popover, and taking steps to make sure that it's properly managed. Start off by editing DudelViewController.h, adding the following code shown in bold. In addition to adding the instance variable (and its matching property declaration), here we're also adding UIPopoverControllerDelegate to the list of protocols this class implements.

@interface DudelViewController : UIViewController <ToolDelegate, DudelViewDelegate, MFMailComposeViewControllerDelegate, UIPopoverControllerDelegate> {
id <Tool> currentTool;
IBOutlet DudelView *dudelView;
IBOutlet UIBarButtonItem *textButton;
IBOutlet UIBarButtonItem *freehandButton;
IBOutlet UIBarButtonItem *ellipseButton;
IBOutlet UIBarButtonItem *rectangleButton;
IBOutlet UIBarButtonItem *lineButton;
IBOutlet UIBarButtonItem *dotButton;
UIColor *strokeColor;
UIColor *fillColor;
UIFont *font;
CGFloat strokeWidth;
UIPopoverController *currentPopover;
}

@property (retain, nonatomic) id <Tool> currentTool;
@property (retain, nonatomic) UIColor *strokeColor;
@property (retain, nonatomic) UIColor *fillColor;
@property (retain, nonatomic) UIFont *font;
@property (assign, nonatomic) CGFloat strokeWidth;
@property (retain, nonatomic) UIPopoverController *currentPopover;


Follow up by switching over to DudelViewController.m to synthesize the currentPopover property, and clean it up in the dealloc method.

@synthesize currentTool, fillColor, strokeColor, font, strokeWidth, currentPopover;

- (void)dealloc {
self.currentTool = nil;
self.fillColor = nil;
self.strokeColor = nil;
self.currentPopover = nil;
[super dealloc];
}

One tricky aspect of dealing with popovers has to do with cleanup after a popover has been dismissed. If the user clicked outside the popover, causing it to be automatically dismissed, then a method will be called in the UIPopoverController's delegate. But if you dismiss the popup from within code, that method isn't called. We'll handle this discrepancy by just making the delegate method call our own cleanup method, handleDismissedPopoverController:, which we'll be careful to call every time we dismiss a popup manually.

- (void)handleDismissedPopoverController:(UIPopoverController*)popoverController {
self.currentPopover = nil;
}
- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController {
[self handleDismissedPopoverController:popoverController];
}


As you can see, our current cleanup method doesn't do much cleanup yet, but that will change!

The main thing we're going to need to do in our cleanup method, besides clearing our currentPopover instance variable, is to get whatever values we need from the popover's displayed controller. In Dudel, we'll implement this by checking for the specific classes we're using for the view controllers. So the handleDismissedPopoverController: method will end up containing a series of if/else blocks, like this:

// just for explanatory purposes, not for copy-and-paste!
if ([popoverController.contentViewController isMemberOfClass:[SomeController class]]) {
// now we know which view controller we're dealing with
SomeController *sc = (SomeController *)popoverController.contentViewController;
// retrieve some values from the controller, to see what the user selected/adjusted
self.something = sc.something;
...
} else if (...)


Yes, I agree that this sort of if/else pileup is distasteful. But it's the simplest solution in this case, and our project is small enough that it's not introducing too much painful ugliness.

Other -----------------
- iPad SDK : Preparing Dudel for a New Tool (part 5) - Rendering Multiple Styles
- iPad SDK : Preparing Dudel for a New Tool (part 4) - Creating a New Drawable Class
- jQuery 1.3 : AJAX - Loading data on demand (part 3) - Loading an XML document
- jQuery 1.3 : AJAX - Loading data on demand (part 2) - Working with JavaScript objects
- jQuery 1.3 : AJAX - Loading data on demand (part 1) - Appending HTML
- Coding JavaScript for Mobile Browsers (part 13) - Zoom and rotate gestures
- Coding JavaScript for Mobile Browsers (part 12) - Swipe gesture
- Coding JavaScript for Mobile Browsers (part 11)
- Coding JavaScript for Mobile Browsers (part 10) - Event Handling
- iPad SDK : Preparing Dudel for a New Tool (part 3) - Creating the Text Tool
- iPad SDK : Preparing Dudel for a New Tool (part 2) - Implementing Changes to the Controller Class
- Coding JavaScript for Mobile Browsers (part 9) - Scripting Styles
- Coding JavaScript for Mobile Browsers (part 8) - DOM
- iPad SDK : Preparing Dudel for a New Tool (part 1) - Setting Up the GUI
- Coding JavaScript for Mobile Browsers (part 7)
- Coding JavaScript for Mobile Browsers (part 6)
- iPad SDK : The Structure of Core Text
- iPad SDK : PDF Generation
- jQuery 1.3 : Sorting and paging (part 5) - Finessing the sort keys
- jQuery 1.3 : Sorting and paging (part 4)
 
 
 
Top 10
 
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
- First look: Apple Watch

- 3 Tips for Maintaining Your Cell Phone Battery (part 1)

- 3 Tips for Maintaining Your Cell Phone Battery (part 2)
programming4us programming4us